package com.beerandjesus.sportofkings.handicapper.factory.brisnet.singlefile;

import com.beerandjesus.sportofkings.handicapper.factory.ProfileFactory;
import com.beerandjesus.sportofkings.handicapper.model.*;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Race;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Horse;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.PastPerformance;
import com.beerandjesus.sportofkings.handicapper.dao.Database;

import java.util.List;
import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;

/**
 * Date: Jun 8, 2012
 * Time: 2:21:28 PM
 */
public class ProfileFactoryImpl implements ProfileFactory {

    private Database database;

    public List<AnalysisProfile> getProfiles(Race race, Horse horse) {
        List<AnalysisProfile> profiles = new ArrayList<AnalysisProfile>();
        AnalysisProfile firstTurf = checkForOnceOrTwiceTurfers(race, horse);
        if (firstTurf != null) {
            profiles.add(firstTurf);
        }
        return profiles;
    }

    private AnalysisProfile checkForOnceOrTwiceTurfers(Race race, Horse horse) {
        // Must be a turf race..
        TrackSurface surface = race.getSurface();
        if (!surface.isTurf()) {
            return null;
        }
        // Must be first or second turf attempt
        int turfRaceCount = 0;
        List<PastPerformance> perfs = horse.getPastPerformances();
        if (perfs != null) {
            for (PastPerformance perf : perfs) {
                if (perf.getSurface() != null && perf.getSurface().isTurf()) {
                    turfRaceCount++;
                }
            }
        }
        if (turfRaceCount >= 2) {
            return null;
        }
        // Check for 2nd try on turf after returning to dirt
        PastPerformance lastRace = null;
        TrackSurface lastRaceSurface = null;
        String lastRaceFinish = null;
        String lastRaceBtwn = null;
        if (perfs != null && perfs.size() > 0) {
            lastRace = perfs.get(0);
            lastRaceSurface = lastRace.getSurface();
            lastRaceFinish = lastRace.getFinishPosition();
            lastRaceBtwn = lastRace.getFinishBtwnLengthsOnly();
            if (turfRaceCount == 1) {
                if (lastRaceSurface != null && !lastRaceSurface.isTurf()) {
                    return AnalysisProfile.getAnalysisProfile(AnalysisProfileType.SECOND_TURF_START_AFTER_RETURNING_TO_DIRT, 0);
                }
            }
        }
        // Must have a performing turf sire
        String sireName = horse.getSireName();
        if (sireName == null) {
            return null;
        }
        TurfSire sire = getDatabase().getTurfSireByName(sireName);
        if (sire == null) {
            return null;
        }
        // This horse passes with a base score of 0.
        int score = 0;
        AnalysisProfileType type = AnalysisProfileType.FIRST_OR_2ND_TURF_STARTER_WITH_PEDIGREE;

        // Are m/l odds 10-1 or more?
        String mlOdds = horse.getMorningLineOdds();
        if (!StringUtils.isEmpty(mlOdds)) {
            if (Double.valueOf(mlOdds) >= 10) {
                score++;
            }
        }

        // Is the dam's sire influential as well?

        String damSireName = horse.getDamSireName();
        if (!StringUtils.isEmpty(damSireName)) {
            TurfSire damSire = getDatabase().getTurfSireByName(damSireName);
            if (damSire != null) {
                score++;
            }
        }

        // Was the last race a turf start within 30 days ago?
        String sinceLastRace = horse.getDaysSinceLastRace();

        if (!StringUtils.isEmpty(sinceLastRace)) {
            double days = Double.valueOf(sinceLastRace);
            if (days <= 30  && lastRace != null) {
                if (lastRaceSurface != null && lastRaceSurface.isTurf()) {
                    score++;
                }
            }
        }

        // Did this horse win its last turf race?
        // Or, did he not win but finish within a length of winner?
        Integer lastRaceFinishInt = null;
        try {
            lastRaceFinishInt = Integer.valueOf(lastRaceFinish);
        } catch (NumberFormatException e) {

        }
        if (lastRaceSurface != null && lastRaceSurface.isTurf() &&
                lastRaceFinishInt != null) {
            if (lastRaceFinishInt == 1) {
                score++;
                type = AnalysisProfileType.SECOND_TURF_START_AFTER_WINNING_ON_TURF;
            } else {
                if (lastRaceBtwn != null) {
                    if (Double.valueOf(lastRaceBtwn) <= 1) {
                        score+= 2;
                        type = AnalysisProfileType.SECOND_TURF_START_AFTER_LOSING_WITH_HONOR;
                    }
                }
            }
        }

        // Is this a maiden or nonwinners allowance race?
        // Actually we only can tell if it's a maiden race..
        RaceType raceType = race.getType();
        if (raceType != null && raceType.isMaiden()) {
            score++;
        }
        return AnalysisProfile.getAnalysisProfile(type, score);
    }

    public Database getDatabase() {
        return database;
    }

    public void setDatabase(Database database) {
        this.database = database;
    }
}
